package ecole.organisation;

import java.util.ArrayList;
import java.util.Date;

import config.Config;
import ecole.infrastructure.Salle;
import ecole.utilisateur.Etudiant;
import ecole.utilisateur.Professeur;

/**
 * classe Groupe : définissant les differnets groupe d'une formation
 * @author Salah Bennour
 */
public class Groupe implements java.io.Serializable{

	
	private static final long serialVersionUID = 2L;
	private ArrayList<Etudiant> listEtudiant = new ArrayList<Etudiant>();
	private ArrayList<Seance> listSeance = new ArrayList<Seance>();
	private String nomGroupe;
	private int typeGroupe = 0;
	private String[] tabTypeGroupe = {"TD","TP","Amphi"};
	private int capacite = 0;
    protected int[] capaciteGroupe = {Config.MAX_GROUPE_TD, Config.MAX_GROUPE_TP, Config.MAX_GROUPE_AMPHI};
    
 // ***************CONSTRUCTEURS*************************
    public Groupe(){}
    public Groupe(int typeGroupe, String nomGroupe){
    		this.nomGroupe = nomGroupe;
    		verifTypeGroupe(typeGroupe);
    		
    }
    
    // ***************METHODES*************************
    /** 
     * Methode permettant d'obtenir tous les etudiants d'un groupe
     * @return ArrayList<Etudiant> :  tous les etudiants du groupe.
     */
    public ArrayList<Etudiant> getListEtudiant() {
		return listEtudiant;
	}
    
    /**
     * Methode permettant d'ajouter un etudiant au groupe
     * @param student : est l'etudiant que l'on souhaite ajouter au groupe.
     */
    public void ajouterEtudiant(Etudiant student){
    	if(capaciteDepasse())
    		listEtudiant.add(student);
    	else 
    		System.out.println("Ce groupe est plein !");
    }
    
    /**
    * Methode permettant de verifier si la capacité maximal du groupe est dépassé
    * @return boolean : true si dépassé; false sinon.
    */
    public boolean capaciteDepasse(){
    	if(capacite > listEtudiant.size())
    		return true;
    	return false;
    }
    
    /**
     * Methode permettant de verifier que le type entrer par l'utilisateur correspond bien à un type de groupe.
     * @return typeGroupe : est le numero du groupe (1 pour Td, 2 pour TP et 3 pour Amphi).
     */
    public void verifTypeGroupe(int typeGroupe){
    	if(typeGroupe > 0 && typeGroupe < 4){
    		this.typeGroupe = typeGroupe;
    		attribuerCapacite(typeGroupe);
    	}
    }
    
    /**
     * Methode permettant d'attribuer un capacité en fonction du groupe choisi( 25 pour un groupe de TD...)
     * @param typeGroupe : est le type du groupe(1 pour Td, 2 pour TP et 3 pour Amphi).
     */
    public void attribuerCapacite(int typeGroupe){
    	this.capacite = capaciteGroupe[typeGroupe-1];
    }
    
    /**
     * Methode permettant de definir si l'etudiant appartient deja a un groupe de TD.
     * @param student est l'instance de la classe Etudiant.
     * @return boolean : si l'etudiant appartient deja a un TD. Sinon false.
     */
    public boolean etudiantAppartientTD(Etudiant student){
    	if(student.getEtudiantAppartientGroupeTD()) 
    		return true;
    	return false;
    }
    
    /**
     * Methode permettant de definir si l'etudiant appartient deja a un groupe de TP.
     * @param student est l'instance de la classe Etudiant.
     * @return boolean : si l'etudiant appartient deja a un TP. Sinon false.
     */
    public boolean etudiantAppartientTP(Etudiant student){
    	if(student.getEtudiantAppartientGroupeTP()) 
    		return true;
    	return false;
    }
    
    /**
     * Methode permettant d'ajouter une seance a un groupe.
     * Elle verifie d'abord que l'etudiant n'appartient a aucun groupe.
     * @param ens est une instance de la classe Enseignement.
     * @param prof est une instance de la classe Professeur.
     * @param date est une instance de la classe Date.
     * @param creneau est le numero du creneau horaire choisi.
     * @param salle est une instance de la classe Salle.
     */
    public void ajouterSeance(Enseignement ens, Professeur prof, Date date ,int creneau, Salle salle)
    {
    	Seance s = new Seance(ens,prof,date,creneau,this); // creation objet seance
    	this.listSeance.add(s); //ajoute la seance à la liste des seances du groupe
    }

   
    /**
     * Methode permettant de supprimer un eleve du groupe.
     * @param number est l'indice de l'etudiant dans l'arrayList
     */
    public void supprimerEtudiant(int number){
    	listEtudiant.remove(number);
    }

    /**
     * Methode permettant de supprimer un eleve du groupe.
     * @param student est l'instance de la classe Etudiant que l'on souhaite supprimer.
     */
    public void supprimerEtudiant(Etudiant student){
    	listEtudiant.remove(student);
    }

    /**
     * Methode permettant de savoir si un groupe est vide.
     *  C'est a dire si aucun etudiant n'appartient a ce groupe.
     * @preturn boolean : true si le groupe est vide. Sinon false.
     */
    public boolean groupeVide(){
		if(listEtudiant.isEmpty()) //si la liste est vide
			return true;
		return false;
    }

    /**
     * Methode permettant de savoir si le nombre d'un groupe est inférieur à la capcité d'un groupe
     * @return boolean : true si le nombre d'etudiant est inférieur à la capacité. False sinon.
     */
    public boolean isNbEtudiantInfCapacite(){
    	return (this.getNombreEtudiantGroupe() < this.getCapacite());
    }

    /**
     * Methode permettant de savoir si un etudiant appartient au groupe.
     * @return boolean : true si l'etudiant appartient au groupe. False sinon.
     */
    public boolean etudiantAppartientGroupe(Etudiant student){
    	return (listEtudiant.contains(student));	
    }
    // ***************GETTER*************************
    /**
     * Methode permettant de retourner la capacité maximal du groupe.
     * @return int : retourne la capacité maximal du groupe
     */
    public int getCapacite(){
    	return capacite;
    }
    
    /**
     * Methode permettant de retourner le type du groupe.
     * @return Strinf : est le nom du type de groupe(ex TD, TP, ou Amphi).
     */
    public String getTypeGroupe(){
    	return tabTypeGroupe[typeGroupe-1];
    }
    
    /**
     * Methode permettant de retourner le numero du type du groupe.
     * @return Strinf : est le nom du type de groupe(ex 1 pour TD, 2 pour TP, et 3 pour Amphi).
     */
    public int getIntTypeGroupe(){
    	return typeGroupe;
    }

    /**
     * Methode permettant de retourner le nom du groupe.
     * @return String : le nom du groupe.
     */
    public String getNomGroupe(){
    	return nomGroupe;
    }
    
    /**
     * Methode permettant de retourner la nombre d'etudiant du groupe.
     * @return int : le nombre d'étudiant dans un groupe.
     */
    public int getNombreEtudiantGroupe(){
    	return this.listEtudiant.size();
    }
    // ***************TO STRING*************************
    public String toString(){
   	 	String etud = "";
   	 	if(!groupeVide()) for(int i= 0; i < listEtudiant.size(); i++)	
   	 		etud = etud + "\n \t \t" + (i+1)+ "\\" + listEtudiant.get(i).getNom() + "" +listEtudiant.get(i).getPrenom()+ "\t \t";	    	
   	 	else etud = "Actuellement aucun etudiant n'est assigner a ce groupe";

	 return "GROUPE \n \t Nom : " +getNomGroupe()+ 
	 "\n \t Type : " +getTypeGroupe()+
	 "\n \t Capacite : "+getCapacite()+
	 "\n \t Liste Etudiant : " +etud+"\n";
    }
}
